/*学习C/C++不定参数*/
#include <iostream>
#include <string>
#include <cstdarg>
#include <cstdlib>
using namespace std;

//__FILE__ 输出执行代码文件来源
//__LINE__ 输出调用__LINE__的代码行数
//__VA_ARGS__ 表示不定参的参数集
//注意：当我们直接输出字符串不指定格式时可能会出现问题 例如 LOG("日志信息"); 此时__VA_ARGS__是一个空的参数 什么都没有，而printf中会多一个 ","
//使用 ##__VA_ARGS__ 表示当__VA_ARGS__为空参数时，去掉其前面的","防止编译错误
// printf("[文件:%s-第%d行]:" fmt,__FILE__,__LINE__,##__VA_ARGS__)   注意 "[文件:%s-第%d行]:"和fmt之间需要有空格 否则会有报错

//宏定义 不定参函数使用
// #define LOG(fmt,...) printf("[文件:%s-第%d行]:" fmt,__FILE__,__LINE__,##__VA_ARGS__)
// int main()
// {
//     LOG("日志\n");
//     return 0;
// }

//C语言 不定参函数使用
// void print(int num,...)
// {
//     va_list ls;
//     va_start(ls,num); //获取不定参数第一个参数的起始地址 从num开始
//     for(int i = 0;i<num;++i)
//         cout<<"num["<<i+1<<"]:"<<va_arg(ls,int)<<endl; //逐一取出参数
    
//     va_end(ls);//将ls指针置空
// }

// //模拟printf
// void myprintf(const char* fmt,...)
// {
//     va_list ls;
//     va_start(ls,fmt);
//     char* res = nullptr;
//     int n = vasprintf(&res,fmt,ls);
//     if(n != -1)
//     {
//         printf(res);
//         free(res);
//     }
//     va_end(ls);
// }



//C++ 不定参函数使用
void print() { cout<<endl; } //无参函数 结束参数包解析

// template<class T,class ...Args>
// void print(const T& val,Args ...args)
// {
//     cout<<val<<" ";
//     //如果参数包不为空 则继续解析参数包 且使用完美转发保证参数属性
//     if((sizeof ...(args))>0) print(std::forward<Args>(args)...);
//     else print();
// }

template<class T,class ...Args>
void print(const T& val,Args ...args)
{
    cout<<val<<" ";
    //print(args...);
    print(std::forward<Args>(args)...);
}

int main()
{
    print(0,1,2,'x',string("1234"));
    return 0;
}